home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 011 / gdmake.arc / MAKE.C next >
Encoding:
C/C++ Source or Header  |  1986-08-26  |  17.4 KB  |  640 lines

  1.  
  2. #include <stdio.h>
  3. #include <dos.h>
  4. #include <ctype.h>
  5.  
  6. #define  TRUE 1
  7. #define  FALSE 0
  8. #define  DEFAULT  "MAKEFILE"
  9. #define  INMAX  255    /* maximum input line length  */
  10. extern  char *getmem() ;
  11. extern int _oserr, errno ;
  12.  
  13.  
  14. struct sym_ptr
  15.   {
  16.   struct sym_str *data ;
  17.   struct sym_ptr *next ;
  18.   } ;
  19.  
  20. struct sym_str
  21.   {
  22.   char symbol[40] ; /* max symbol size in lattice c is 39 chars */
  23.   char equals[81] ; /* so we had to default to something */
  24.   } ;
  25.  
  26. /* declare some global variables for the symbols */
  27. struct sym_ptr list ;
  28. struct sym_ptr *current ; /* pointer to the current symbol */
  29.                           /* thus we know where to add more to */
  30.  
  31. struct howrec {
  32.   char *howcom,*howargs;
  33.   struct  howrec *nexthow;
  34. };
  35.  
  36. struct deprec {
  37.   char *name;
  38.   struct  defnrec  *def;
  39.   struct  deprec *nextdep;
  40. };
  41.  
  42. struct defnrec {
  43.   char *name;
  44.   int uptodate;
  45.   long modified;
  46.   struct  deprec *dependson;
  47.   struct  howrec *howto;
  48.   struct  defnrec  *nextdefn;
  49. };
  50.  
  51. struct dorec {
  52.   char *name;
  53.   struct  dorec *nextdo;
  54. };
  55.  
  56. struct defnrec *defnlist;
  57. struct dorec *dolist;
  58.  
  59. int execute;
  60. int stopOnErr;
  61. int madesomething;
  62. int knowhow;
  63.  
  64. main(argc,argv)
  65. int argc;
  66. char *argv[];
  67. {
  68.   long make();
  69.   long void ;
  70.   current = &list ;
  71.   current->next = NULL ;
  72.   current->data = NULL ;
  73.   init(argc,argv);
  74.  
  75.   /* now  fall down the dolist and  do them  all */
  76.   while (dolist != NULL)  {
  77.     madesomething  =  FALSE;
  78.     void = make(dolist->name);    /* ignore return value */
  79.     if (!madesomething) {
  80.       if (knowhow)
  81.         fprintf(stderr,"Make: '%s' is up to  date\n",dolist->name);
  82.       else  {
  83.         fprintf(stderr,"Make: Don't  know how to  make '%s'\n",
  84.           dolist->name);
  85.         if (stopOnErr)
  86.           exit(-1);
  87.       }
  88.     }
  89.     dolist = dolist->nextdo;
  90.   }
  91. }
  92.  
  93. init(argc,argv)
  94. int argc;
  95. char *argv[];
  96. {
  97.   int i,  usedefault;
  98.   dolist  = NULL;
  99.   defnlist = NULL;
  100.   usedefault = TRUE;
  101.   execute  = TRUE;
  102.   stopOnErr = TRUE;
  103.  
  104.   for (i=1; i < argc; i++) {
  105.     if (argv[i][0] == '-') {  /* option */
  106.       switch (argv[i][1]) {
  107.         case 'f': case 'F':  /* arg following is a makefile */
  108.           if  (++i  < argc)  {
  109.             readmakefile(argv[i]);
  110.             usedefault = FALSE;
  111.           } else {
  112.             fprintf(stderr,"Make: '-f' requires filename\n");
  113.             exit(-1);
  114.           }
  115.           break;
  116.         case 'i': case 'I':  /* ignore errors on execution */
  117.           stopOnErr = FALSE;
  118.           break;
  119.         case 'n': case 'N':  /* don't execute commands - just print */
  120.           execute  = FALSE;
  121.           break;
  122.         default:
  123.           fprintf(stderr,"Make: unknown option '%s'\n",argv[i]);
  124.       }
  125.     } else {  /* it must be something  to make  */
  126.       add_do(argv[i]);
  127.     }
  128.   }
  129.   if (usedefault)
  130.     readmakefile(DEFAULT);
  131.  
  132. }
  133.  
  134. long make(s)  /*  returns  the modified  date/time */
  135. char *s;
  136. {
  137.   struct  defnrec  *defnp;
  138.   struct  deprec *depp;
  139.   struct  howrec *howp;
  140.   char    exp_args[128] ;
  141.   char    system_call[255] ;
  142.   long latest, getmodified(), lmax(), currtime();
  143.   int void, return_code ;
  144.  
  145.   /* look  for the  definition */
  146.   defnp =  defnlist;
  147.   while (defnp !=  NULL) {
  148.     if (strcmp(defnp->name,s) == 0)
  149.       break;
  150.     defnp  =  defnp->nextdefn;
  151.   }
  152.  
  153.   if (defnp == NULL) {  /* don't know how  to make  it */
  154.     knowhow  = FALSE;
  155.     latest = getmodified(s);
  156.     if (latest==0) {  /* doesn't exist but  don't know  how to make */
  157.       fprintf(stderr,"Make: Can't make '%s'\n",s);
  158.       exit(-1);
  159.     } else  /* exists - assume it's  up to date since we don't know  */
  160.       return(latest);
  161.   }
  162.  
  163.   if (defnp->uptodate)
  164.     return(defnp->modified);
  165.  
  166.   /* now  make sure everything that it depends on  is up to  date */
  167.   latest  = 0;
  168.   depp =  defnp->dependson;
  169.   while (depp !=  NULL) {
  170.     latest = lmax(make(depp->name),latest);
  171.     depp = depp->nextdep;
  172.   }
  173.  
  174.   knowhow  = TRUE;  /* has  dependencies therefore we know how */
  175.  
  176.   /* if necessary, execute all of  the commands to  make it  */
  177.   /* if (out of date) ||  (depends  on nothing)    */
  178.   if (latest > defnp->modified ||  defnp->dependson==NULL)  {
  179.     /* make  those  suckers  */
  180.     howp = defnp->howto;
  181.     while  (howp != NULL) {
  182.       expand_args(howp->howargs, exp_args) ;
  183.       printf("%s %s\n",howp->howcom,exp_args);
  184.       if (execute)
  185.         {
  186.         void = forklp(howp->howcom,exp_args,NULL) ;
  187.         if (void == 0) /* success loading function */
  188.           {
  189.           /* now do a wait to see if the function returns an ok code */
  190.           return_code = wait() ;
  191.           if (return_code != 0) /* error code returned */
  192.             {
  193.             printf("MAKE: error returned from %s %s, code = %d\n",
  194.                    howp->howcom, exp_args, return_code ) ;
  195.             if  (stopOnErr)
  196.               exit(-1);
  197.             } /* endif return_code != 0 */
  198.           }
  199.         else
  200.           { /* fork had an error loading */
  201.           if (_oserr == 2) /* error for file not found */
  202.             { /* lets do a system call instead then */
  203.             strcpy( system_call, howp->howcom ) ;
  204.             strcat( system_call, " " ) ;
  205.             strcat( system_call, exp_args ) ;
  206.             void = system( system_call ) ;
  207.             if (void != 0) /* error in system call */
  208.               {
  209.               printf("MAKE: system call error from %s %s, code = %d\n",
  210.                      howp->howcom, exp_args, _oserr ) ;
  211.               if  (stopOnErr)
  212.                 exit(-1);
  213.               } /* endif id void != 0 */
  214.             }
  215.           else
  216.             {
  217.             printf("\nMake: error on '%s %s' _oserr = %d\n",
  218.                 howp->howcom,exp_args, _oserr);
  219.             if  (stopOnErr)
  220.               exit(-1);
  221.             } /* endif _oserr == 2 */
  222.           } /* endif void == 0 */
  223.         } /* endif execute */
  224.       howp  = howp->nexthow;
  225.     } /* end while */
  226.     defnp->modified  = currtime();
  227.     defnp->uptodate  = TRUE;
  228.     if (defnp->howto != NULL)  /* we had instructions */
  229.       madesomething =  TRUE;
  230.   }
  231.  
  232.   return(defnp->modified);
  233.  
  234. }
  235.  
  236. expand_args( in, out )
  237. char *in, *out ;
  238.   {
  239.   char *posin, *posout, *possym ;
  240.   char symbol[40] ;
  241.   char *get_symval(), *symval ;
  242.  
  243.   posin = in ;
  244.   posout = out ;
  245.   while (TRUE)
  246.     {
  247.     while ( (*posin != '$') && (*posin != '\0') )
  248.       *posout++ = *posin++ ; /* copy till we find a $ */
  249.  
  250.     if (*posin == '\0') /* have reached the end of the input */
  251.       {                 /* so exit */
  252.       *posout = '\0' ;  /* terminate the output string first tho */
  253.       return ;
  254.       }
  255.  
  256.     possym = symbol ;   /* point symbol pointer at the begining */
  257.     /* skip over the $ so we can test for alphanumeric */
  258.     *possym++ = *posin++ ; /* copy's the $ */
  259.     while ( isalnum(*posin) )
  260.       *possym++ = *posin++ ; /* copy in the suspected symbol */
  261.     *possym = '\0' ; /* zero terminate it */
  262.     /* get the value of the found symbol */
  263.     if ( (symval = get_symval( symbol )) == NULL )
  264.       { /* do this if there isn't a symbol match */
  265.       possym = symbol ; /* reset the symbol position */
  266.       /* copy the symbol to the output */
  267.       while (*possym != '\0' )
  268.         *posout++ = *possym++ ;
  269.       }
  270.     else /* do this if there is one */
  271.       {
  272.       /* copy the symbol equate to the output */
  273.       while (*symval != 0)
  274.         *posout++ = *symval++ ;
  275.       }
  276.     }
  277.     /* should never get to here */
  278.   return ;
  279.   }
  280.  
  281. char *get_symval( symbol )
  282. char *symbol;
  283.   {
  284.   struct sym_ptr *cur_ptr ;
  285.  
  286.   cur_ptr = &list ;             /* start at the begining of the list */
  287.   while (cur_ptr->data != NULL) /* while there is data */
  288.     {
  289.     if (strcmp(cur_ptr->data->symbol, symbol) == 0) /* they match */
  290.       {
  291.       return(cur_ptr->data->equals) ; /* return the pointer to */
  292.                                       /* the equate string */
  293.       }
  294.     else /* they dont */
  295.       cur_ptr = cur_ptr->next ; /* point cur_ptr to the next symbol */
  296.     }
  297.   return(NULL) ;
  298.   }
  299.  
  300. add_do(s)
  301. char *s;
  302. {
  303.   struct  dorec *ptr1, *ptr2;
  304.   char *get_mem();
  305.  
  306.   ptr1 =  (struct  dorec *)get_mem(sizeof(struct dorec));
  307.  
  308.   ptr1->name = s;  /* okay  since only called with  an argv  */
  309.   ptr1->nextdo =  NULL;
  310.  
  311.   uppercase(ptr1->name);
  312.  
  313.   /* now  go down  the dolist */
  314.   if (dolist == NULL)
  315.     dolist = ptr1;
  316.   else {
  317.     ptr2 = dolist;
  318.     while  (ptr2->nextdo != NULL)
  319.       ptr2  = ptr2->nextdo;
  320.     ptr2->nextdo = ptr1;
  321.   }
  322.  
  323. }
  324.  
  325.  
  326. readmakefile(s)
  327. char *s;
  328. {
  329.   int doneline, pos, i, j;
  330.   long getmodified() ;
  331.   FILE *fil ;
  332.   char inline[INMAX], info[INMAX];
  333.   char *get_mem();
  334.   struct  defnrec  *defnp,  *defnp2;
  335.   struct  deprec *depp, *depp2;
  336.   struct  howrec *howp, *howp2;
  337.  
  338.   if ( (fil = fopen(s,"r")) == NULL)
  339.     {
  340.     fprintf(stderr,"Make:  Couldn't open '%s'\n",s);
  341.     return;
  342.     }
  343.  
  344.   while (fgets(inline,INMAX,fil)  != NULL)
  345.     {
  346.     inline[strlen(inline)-1] = '\0';  /* strip trailing newline */
  347.  
  348.     if (inline[0]  == '\0')  /* ignore blank  lines */
  349.       continue;
  350.  
  351.     switch (inline[0])
  352.       {
  353.       default:
  354.         uppercase(inline);
  355.  
  356.         /* get what we're defining into  info  */
  357.         if (sscanf(inline,"%s ",info) != 1)
  358.           {
  359.           fprintf(stderr,"Make: Can't  scan: '%s'\n",inline);
  360.           continue;
  361.           }
  362.         /* get a new  struct */
  363.         defnp =  (struct  defnrec  *)get_mem(sizeof(struct  defnrec));
  364.         /* add it to  the end  of  defnlist */
  365.         if (defnlist  ==  NULL)
  366.           defnlist = defnp;
  367.         else
  368.           {
  369.           defnp2 = defnlist;
  370.           while (defnp2->nextdefn  != NULL)
  371.             defnp2 = defnp2->nextdefn;
  372.           defnp2->nextdefn = defnp;
  373.           }
  374.         /* initialize it */
  375.         defnp->name = get_mem(strlen(info)+1);
  376.         strcpy(defnp->name,info);
  377.         defnp->uptodate  = FALSE;  /* actually  unknown  */
  378.         defnp->modified  = getmodified(defnp->name);
  379.         defnp->dependson = NULL;
  380.         defnp->howto  = NULL;
  381.         defnp->nextdefn  = NULL;
  382.  
  383.         /* now go through all of its  dependecies */
  384.         /* first move past the first  name */
  385.         pos = 0;
  386.         while (isspace(inline[pos]))
  387.           pos++;
  388.         while (!isspace(inline[pos])  &&  inline[pos]!='\0')
  389.           pos++;
  390.         /* now loop through those suckers */
  391.         doneline = FALSE;
  392.         while (!doneline)
  393.           {
  394.           while (isspace(inline[pos]))
  395.             pos++;
  396.           if (inline[pos] == '\0')
  397.             {
  398.             doneline =  TRUE;
  399.             continue;
  400.             }
  401.           for(i =  0; !isspace(inline[pos]) &&  inline[pos]!='\0'; )
  402.             info[i++] = inline[pos++];
  403.           info[i]  = '\0';
  404.           /* get a new struct  */
  405.           depp = (struct deprec *)get_mem(sizeof(struct deprec));
  406.           /* add it to the end of  deplist  */
  407.           if (defnp->dependson ==  NULL)
  408.             defnp->dependson =  depp;
  409.           else
  410.             {
  411.             depp2 =  defnp->dependson;
  412.             while (depp2->nextdep != NULL)
  413.               depp2 =  depp2->nextdep;
  414.             depp2->nextdep = depp;
  415.             }
  416.           depp->name = get_mem(strlen(info)+1);
  417.           strcpy(depp->name,info);
  418.           depp->nextdep =  NULL;
  419.           }
  420.         break ;
  421.       case '+': /* must be a continuation line */
  422.         uppercase(inline);
  423.  
  424.         /* now go through all of its  dependecies */
  425.         /* first move past the + sign */
  426.         pos = 1;
  427.         /* now loop through those suckers */
  428.         doneline = FALSE;
  429.         while (!doneline)
  430.           {
  431.           while (isspace(inline[pos]))
  432.             pos++;
  433.           if (inline[pos] == '\0')
  434.             {
  435.             doneline =  TRUE;
  436.             continue;
  437.             }
  438.           for(i =  0; !isspace(inline[pos]) &&  inline[pos]!='\0'; )
  439.             info[i++] = inline[pos++];
  440.           info[i]  = '\0';
  441.           /* get a new struct  */
  442.           depp = (struct deprec *)get_mem(sizeof(struct deprec));
  443.           /* add it to the end of  deplist  */
  444.           if (defnp->dependson ==  NULL)
  445.             defnp->dependson =  depp;
  446.           else
  447.             {
  448.             depp2 =  defnp->dependson;
  449.             while (depp2->nextdep != NULL)
  450.               depp2 =  depp2->nextdep;
  451.             depp2->nextdep = depp;
  452.             }
  453.           depp->name = get_mem(strlen(info)+1);
  454.           strcpy(depp->name,info);
  455.           depp->nextdep =  NULL;
  456.           }
  457.         break ;
  458.       case '$': /* must be a symbol definition */
  459.         /* now split  the line up into symbol and args */
  460.         for (pos=0;isspace(inline[pos]); pos++);
  461.           ;
  462.         for (i=pos; !isspace(inline[i])  && inline[i]!='\0'; i++)
  463.           ;
  464.         /* if there is something there,  allocate mem  and copy */
  465.         if (i != pos)
  466.           {
  467.           /* get a new struct  */
  468.           current->data = (struct sym_str *)get_mem(sizeof(struct sym_str));
  469.           current->next = (struct sym_ptr *)get_mem(sizeof(struct sym_ptr));
  470.           for(j=0; pos < i; )
  471.             current->data->symbol[j++] = inline[pos++] ;
  472.           current->data->symbol[j] = '\0';
  473.           /* now look  for  any  argumentative part */
  474.           while (isspace(inline[pos]))
  475.             pos++;
  476.           for(i=0; inline[pos] !=  '\0'; )
  477.             current->data->equals[i++] = inline[pos++] ;
  478.           current->data->equals[i] = '\0' ;
  479.           current = current->next ;
  480.           current->next = NULL ;
  481.           current->data = NULL ;
  482.           }
  483.         break ;
  484.       case '\t':
  485.         if (defnp ==  NULL)
  486.           {
  487.           fprintf(stderr,"Make: Howto  line without a definition\n");
  488.           fprintf(stderr,"Make: '%s'\n",inline);
  489.           }
  490.         /* now split  the line up into command and args */
  491.         for (pos=0;isspace(inline[pos]); pos++);
  492.           ;
  493.         for (i=pos; !isspace(inline[i])  && inline[i]!='\0'; i++)
  494.           ;
  495.         /* if there is something there,  allocate mem  and copy */
  496.         if (i != pos)
  497.           {
  498.           /* get a new struct  */
  499.           howp = (struct howrec *)get_mem(sizeof(struct howrec));
  500.           /* add it to the end of  howlist  */
  501.           if (defnp->howto ==  NULL)
  502.             defnp->howto = howp;
  503.           else
  504.             {
  505.             howp2 =  defnp->howto;
  506.             while (howp2->nexthow != NULL)
  507.               howp2 =  howp2->nexthow;
  508.             howp2->nexthow = howp;
  509.             }
  510.           /* copy  command  filename */
  511.           howp->howcom = get_mem(i-pos+1);
  512.           for(j=0; pos < i; )
  513.             howp->howcom[j++] = inline[pos++];
  514.           howp->howcom[j]  = '\0';
  515.           /* now look  for  any  argumentative part */
  516.           while (isspace(inline[pos]))
  517.             pos++;
  518.           howp->howargs =  get_mem(strlen(inline)-pos + 1);
  519.           for(i=0; inline[pos] !=  '\0'; )
  520.             howp->howargs[i++]  = inline[pos++];
  521.           howp->howargs[i] = '\0';
  522.           howp->nexthow =  NULL;
  523.           } /* if */
  524.         break ;
  525.       } /* switch */
  526.     } /* while */
  527.   fclose(  fil ) ;
  528. }  /* readmakefile */
  529.  
  530.  
  531. uppercase(s)
  532. char *s;
  533. {
  534.  
  535.   for( ;  *s != '\0'; s++)
  536.     *s = toupper(*s);
  537. }
  538.  
  539.  
  540. char *get_mem(size)    /* different name to differentiate it */
  541. int size;     /* from lattice C 2.11  function */
  542. {
  543.   char *p;
  544.  
  545.   if ((p  = getmem(size))  == NULL)  {
  546.     fprintf(stderr,"Make:  Ran out  of memory...\n");
  547.     exit(-1);
  548.   }
  549.   return(p);
  550. }
  551.  
  552.  
  553. long getmodified(name)
  554. char *name;
  555. {
  556.    struct  dt_tm {
  557.      int  time ;
  558.      int  date ;
  559.       } ;
  560.  
  561.    union vals {
  562.      long  ret_dt  ;
  563.      struct dt_tm  dt ;
  564.      } out_val ;
  565.  
  566.    union  REGS in_regs ;
  567.    union  REGS out_regs ;
  568.  
  569.    union FLAGS ret_flags ;
  570.    int file_handle ;
  571.  
  572.    /* get  the file handle  */
  573.    in_regs.x.dx =  (int)name ;
  574.    in_regs.h.al =  0 ;
  575.    in_regs.h.ah =  0x3d ;
  576.    ret_flags.all_flags = intdos( &in_regs, &out_regs )  ;
  577.    file_handle =  out_regs.x.ax ;
  578.    /* if  the file  doesn't  exist then return 0 for  date&time */
  579.    if ((ret_flags.flags.cf == 1) && ((file_handle == 2) ||
  580.                                (file_handle == 4) ||
  581.                                (file_handle == 5) ||
  582.                                (file_handle == 12)))
  583.      {
  584.      return( 0 )  ;
  585.      }
  586.  
  587.    /* get  the date */
  588.    in_regs.x.bx =  file_handle ;
  589.    in_regs.h.al =  0 ;
  590.    in_regs.h.ah =  0x57 ;
  591.    intdos( &in_regs, &out_regs )  ;
  592.    out_val.dt.date = out_regs.x.dx ;
  593.    out_val.dt.time = out_regs.x.cx ;
  594.  
  595.    /* close out the file  */
  596.    in_regs.x.bx =  file_handle ;
  597.    in_regs.h.ah =  0x3e ;
  598.    intdos( &in_regs, &out_regs )  ;
  599.    return( out_val.ret_dt  ) ;
  600.  
  601. }
  602.  
  603. long currtime()
  604. /* return a long encoding the current date and time */
  605. {
  606.    union  {
  607.      long  ret_dt  ;
  608.      int  dt[2] ;
  609.      } out_val ;
  610.  
  611.    union  REGS in_regs ;
  612.    union  REGS out_regs ;
  613.  
  614.    in_regs.h.al =  0 ;
  615.    in_regs.h.ah =  0x2a ;
  616.    intdos( &in_regs, &out_regs )  ;
  617.    out_regs.x.cx  -= 1980  ;
  618.  
  619.    out_val.dt[1]  = (out_regs.x.cx  << 9) ;
  620.    out_val.dt[1]  |= (out_regs.h.dh << 5)  ;
  621.    out_val.dt[1]  |= (out_regs.h.dl ) ;
  622.  
  623.    in_regs.h.al =  0 ;
  624.    in_regs.h.ah =  0x2c ;
  625.    intdos( &in_regs, &out_regs )  ;
  626.    out_val.dt[0]  = (out_regs.h.ch  << 11)  ;
  627.    out_val.dt[0]  |= (out_regs.h.cl << 5)  ;
  628.    out_val.dt[0]  |= (out_regs.h.dh >> 1)  ;
  629.    return( out_val.ret_dt  ) ;
  630.  
  631. }
  632.  
  633. long lmax(a,b)
  634. long a,b;
  635. {
  636.   return(a>b ? a  : b);
  637. }
  638. /* ---------- */
  639.  
  640.